package io.jari.dumpert.api;
import android.app.Activity;
import android.content.Context;
import android.preference.PreferenceManager;
import android.util.Base64;
import android.util.Log;
import io.jari.dumpert.Utils;
import io.jari.dumpert.thirdparty.SerializeObject;
import io.jari.dumpert.thirdparty.TimeAgo;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONException;
import org.json.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import java.io.IOException;
import java.io.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Locale;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* JARI.IO
* Date: 11-12-14
* Time: 21:58
*/
public class API {
static String TAG = "DAPI";
static Object getFromCache(Context context, String key) {
String raw = context.getSharedPreferences("dumpert", 0).getString(key, null);
if(raw == null) return null;
return SerializeObject.stringToObject(raw);
}
static void saveToCache(Context context, String key, Serializable object) {
context.getSharedPreferences("dumpert", 0).edit().putString(key, SerializeObject.objectToString(object)).apply();
}
/**
* getListing fetches a listing of items and parses them into a Item array.
* Returns cache if in offline mode.
*/
public static Item[] getListing(Integer page, Context context, String path) throws IOException, ParseException {
String cacheKey = "frontpage_"+page+"_"+path.replace("/", "");
if(Utils.isOffline(context)) {
Object cacheObj = API.getFromCache(context, cacheKey);
//if no cached data present, return empty array
if(cacheObj == null) return new Item[0];
else {
return (Item[])cacheObj;
}
}
Connection connection = Jsoup.connect("http://www.dumpert.nl" + path + ((page != 0) ? page : ""));
if(PreferenceManager.getDefaultSharedPreferences(context).getBoolean("nsfw", false)) connection.cookie("nsfw", "1");
Document document = connection.get();
Elements elements = document.select(".dump-cnt .dumpthumb");
ArrayList<Item> itemArrayList = new ArrayList<Item>();
for(Element element : elements) {
Item item = new Item();
item.url = element.attr("href");
item.title = element.select("h1").first().text();
Log.d(TAG, "Parsing '"+item.url+"'");
item.description = element.select("p.description").first().html();
item.thumbUrl = element.select("img").first().attr("src");
String rawDate = element.select("date").first().text();
Date date = new SimpleDateFormat("dd MMMM yyyy kk:ss", new Locale("nl", "NL")).parse(rawDate);
item.date = new TimeAgo(context).timeAgo(date);
item.stats = element.select("p.stats").first().text();
item.photo = element.select(".foto").size() > 0;
item.video = element.select(".video").size() > 0;
item.audio = element.select(".audio").size() > 0;
if(item.video)
item.imageUrls = new String[] { item.thumbUrl.replace("sq_thumbs", "stills") };
else if(item.photo) {
//get the image itself from it's url.
//sadly no other way to get full hq image :'(
Log.d(TAG, "Got image, requesting "+item.url);
Connection imageConn = Jsoup.connect(item.url);
if(PreferenceManager.getDefaultSharedPreferences(context).getBoolean("nsfw", false)) imageConn.cookie("nsfw", "1");
Document imageDocument = imageConn.get();
ArrayList<String> imgs = new ArrayList<String>();
for(Element img : imageDocument.select("img.player")) {
imgs.add(img.attr("src"));
}
item.imageUrls = new String[imgs.size()];
imgs.toArray(item.imageUrls);
}
itemArrayList.add(item);
}
Item[] returnList = new Item[itemArrayList.size()];
itemArrayList.toArray(returnList);
saveToCache(context, cacheKey, returnList);
return returnList;
}
public static Item[] getListing(Context context, String path) throws IOException, ParseException {
return API.getListing(0, context, path);
}
public static ItemInfo getItemInfo(Item item, Activity context) throws IOException, JSONException {
Document document = Jsoup.connect(item.url).get();
ItemInfo itemInfo = new ItemInfo();
itemInfo.itemId = document.select("body").first().attr("data-itemid");
if(item.video) {
String rawFiles = document.select(".videoplayer").first().attr("data-files");
rawFiles = new String(Base64.decode(rawFiles, Base64.DEFAULT), "UTF-8");
JSONObject files = new JSONObject(rawFiles);
if(PreferenceManager.getDefaultSharedPreferences(context).getString("video_quality", "hd").equals("hd"))
itemInfo.media = files.getString("tablet");
else
itemInfo.media = files.getString("mobile");
} else if(item.audio) {
itemInfo.media = document.select(".dump-player").first().select(".audio").first().attr("data-audurl");
}
return itemInfo;
}
public static Comment[] getComments(String itemId, Context context) throws IOException {
HttpClient httpclient = new DefaultHttpClient();
HttpGet httpget = new HttpGet("http://dumpcomments.geenstijl.nl/"+itemId+".js");
ResponseHandler<String> responseHandler = new BasicResponseHandler();
String file = httpclient.execute(httpget, responseHandler);
Pattern pattern = Pattern.compile("comments\\.push\\('(<[p|footer|article].*)'\\);");
Matcher matcher = pattern.matcher(file);
StringBuilder rawDoc = new StringBuilder();
while(matcher.find()) {
rawDoc.append(matcher.group(1));
}
Document document = Jsoup.parse(rawDoc.toString());
ArrayList<Comment> comments = new ArrayList<Comment>();
Elements elements = document.select("article");
for(Element element : elements) {
Comment comment = new Comment();
comment.id = element.attr("id").substring(1);
Element p = element.select("p").first();
comment.content = p != null ? p.html().replace("\\\"", "\"").replace("\\'", "'").replace("\\"", "") : "";
String footer = element.select("footer").first().text();
StringTokenizer tokenizer = new StringTokenizer(footer, "|");
comment.author = tokenizer.nextToken().trim();
comment.time = tokenizer.nextToken().trim();
comments.add(comment);
}
//modlinks
Pattern modlinksPattern = Pattern.compile("modscr\\.setAttribute\\('src','(.*)'\\)");
Matcher modlinksMatcher = modlinksPattern.matcher(file);
ArrayList<Comment>newComments = new ArrayList<Comment>();
if(modlinksMatcher.find()) {
String modlinksUrl = modlinksMatcher.group(1);
httpget = new HttpGet(modlinksUrl);
String modlinksFile = httpclient.execute(httpget, responseHandler);
//best comments
Pattern bestPattern = Pattern.compile("bestcomments = \\[(([0-9]+)(,\\s)?)+\\];");
Matcher bestMatcher = bestPattern.matcher(modlinksFile);
ArrayList<String> bestComments = new ArrayList<String>();
while(bestMatcher.find()) {
bestComments.add(bestMatcher.group(1));
}
//first loop adds best comments @ top
for(Comment comment: comments) {
if(bestComments.contains(comment.id)) {
comment.best = true;
newComments.add(comment);
}
}
//second loop adds the comments that aren't best
for(Comment comment: comments) {
if(!bestComments.contains(comment.id)) {
newComments.add(comment);
}
}
//scores
Pattern scoresPattern = Pattern.compile("moderation\\['([0-9]*)'] = '(-?[0-9]*)';");
Matcher scoresMatcher = scoresPattern.matcher(modlinksFile);
while (scoresMatcher.find()) {
String id = scoresMatcher.group(1);
String score = scoresMatcher.group(2);
for(Comment comment: newComments) {
if(comment.id.equals(id)) {
Integer index = newComments.indexOf(comment);
comment.score = Integer.parseInt(score);
newComments.set(index, comment);
}
}
}
}
Comment[] returnArr = new Comment[newComments.size()];
newComments.toArray(returnArr);
return returnArr;
}
}